package com.competition.jingdong;

import java.nio.file.Paths;
import java.util.*;
//问题3物品全部挤压: 3312  空间全部合并  使用袋子
public class MainSolution1 {
    static String filepath = "C:\\Users\\henry\\Desktop\\huawei\\京东鲸盘打包下载\\初赛A榜-三维装箱算法";
    static String filename1 = "sku数据.csv";
    static String filename2 = "订单数据.csv";
    static String filename3 = "耗材数据.csv";
    static String filename4 = "青柠味可乐-订单数据.csv";
    static String filename5 = "青柠味可乐-耗材数据.csv";
    static String charsetname1 = "GBK";
    static String charsetname2 = "GBK";
    static String charsetname3 = "UTF-8";
    static HashMap<Integer,Sku> skuHashMap = new HashMap<>();
    static LinkedList<Order> orderLinkedList = new LinkedList<>();
    static LinkedList<Consume> consumeBoxLinkedList = new LinkedList<>();
    static int usedMaxLength=0,usedMaxWeight=0,usedMaxHigh=0;
    static HashSet<NewConsume> newConsumeSet = new HashSet<>();
    static int newConsumeNo  = 1;
    static int packageNo=1;
    public static void main(String[] args) {
        Long startTime = System.currentTimeMillis();
        /*
        第一部分:处理csv文件
         */
        //SKU编码-->skuNo,长-->length,宽-->weight,高-->high,SKU是否可以变形-->change
        //订单号-->orderNo,SKU编码-->skuNo,数量-->count
        //耗材名称-->consumeName,耗材类型-->consumeType,长-->length,宽-->weight,高-->high
        new SkuCsvProcess().processing(Paths.get(filepath,filename1),charsetname1,skuHashMap);
        new OrderCsvProcess().processing(Paths.get(filepath,filename2),charsetname2,orderLinkedList);
        new ConsumeCsvProcess().processing(Paths.get(filepath,filename3),charsetname3,consumeBoxLinkedList);
        Long MAX_BOX = consumeBoxLinkedList.getFirst().volume;
        Long MIN_BOX = consumeBoxLinkedList.getLast().volume;
        System.out.println("************************************************************************");
        System.out.println("最大箱子容量:"+MAX_BOX);
        System.out.println("最小箱子容量:"+MIN_BOX);
        System.out.println("************************************************************************");
        /*
         * 循环处理订单
         * */
        //问题1:
        WriteToCsv writer = new WriteToCsv(Paths.get(filepath,filename4));
        writer.clear();
        solution(MAX_BOX,1,writer);

        //问题2:箱子
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////
        LinkedList<NewConsume> list = new LinkedList<>(newConsumeSet);
        Collections.sort(list);
        int step = list.size()/10;
        for(NewConsume nc:list)
        {
            System.out.println(nc);
        }
        writer = new WriteToCsv(Paths.get(filepath,filename5));
        writer.clear2();
        //找10个合适的型号箱子,写入文件
        LinkedList<NewConsume> newConsumeLinkedList = new LinkedList<>();
        for(int i=0;i<10;i++)
        {
            newConsumeLinkedList.add(list.get(i*step));
        }
        writer.write2(newConsumeLinkedList);
        //根据问题2的10个箱子进行问题1的重新解答
        MAX_BOX = newConsumeLinkedList.getFirst().volume;
        MIN_BOX = newConsumeLinkedList.getLast().volume;
        System.out.println("*****************************");
        consumeBoxLinkedList.clear();
        for(NewConsume nc:newConsumeLinkedList)
        {
            System.out.println(nc);
            consumeBoxLinkedList.add(new Consume(nc));
        }
        //问题2:对问题1重新解答:
        //追加写
        writer = new WriteToCsv(Paths.get(filepath,filename4));
        solution(MAX_BOX,2,writer);


        //问题3:有变形
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////
        //更改可变形数据:
        for(Integer i:skuHashMap.keySet())
        {
            Sku s = skuHashMap.get(i);
            if(s.change)
            {
                s.length = (int)Math.ceil(s.length*0.9);
                s.weight = (int)Math.ceil(s.weight*0.9);
                s.high = (int)Math.ceil(s.high*0.9);
                s.volume = ((long) s.length *s.weight*s.high);
                s.change = false;
                skuHashMap.put(i,s);
            }
        }
        solution(MAX_BOX,3,writer);
        Long endTime = System.currentTimeMillis();
        System.out.println("总耗时:"+(endTime-startTime)+"ms");
    }

    /*
    静态方法区
     */
    static void solution(long MAX_BOX,int problem,WriteToCsv writer)
    {
        for(Order order_i :orderLinkedList)
        {
            packageNo=1;
            //处理一个订单
            //商品按体积降序排列
            LinkedList<SkuSet> orderSkuLinkedList = new LinkedList<>();
            Double orderVolume= (double) 0;
            Integer orderSkuCount = 0;
            //获取到订单信息,计算体积,数量等
            getOrderIno(order_i,orderSkuLinkedList,orderVolume,orderSkuCount);
            //对订单商品-数量进行排序,按体积降序排
            Collections.sort(orderSkuLinkedList);
            for(SkuSet elem:orderSkuLinkedList)
                System.out.println(elem);
            //尝试装箱 1:订单商品总体积小于最大的一个箱子
            System.out.println("************************************************************************");
            System.out.println("开始装箱");
            System.out.println("************************************************************************");
            if(orderVolume<MAX_BOX)
            {
                //初始化包裹号码为1
                //问题1:箱子
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                ////////////////////////////////////////////////////////////////////////////////////////////////////////
                //第一步尝试用一个箱子装下
                int boxNum=0;
                System.out.println();
                boolean oneBoxIsOk=false;


                while(orderSkuLinkedList.size()!=0)
                {
                    boxNum=getConsumeNumInOrderSkuLinkedList(orderSkuLinkedList);
                    System.out.println("********************************选择箱子****************************************");
                    System.out.println("当前选择箱子编号:"+boxNum+" , "+consumeBoxLinkedList.get(boxNum));
                    System.out.println("************************************************************************");
                    LinkedList<OrderData> orderDataLinkedList = new LinkedList<>();
                    while((oneBoxIsOk=tryOneBox(problem,boxNum,order_i.orderNo,packageNo,orderSkuLinkedList,orderDataLinkedList))!=true)
                    {
                        boxNum--;
                        orderDataLinkedList.clear();
                        if(boxNum<0)
                            break;
                    }
                    //一个箱子装不下则选用其他箱子
                    if(oneBoxIsOk==false)
                    {
                        System.out.println("一个箱子装不下");
                        tryAllRoom(problem,0,order_i.orderNo,packageNo,orderSkuLinkedList,orderDataLinkedList);
                        //包裹号码+1
                        packageNo++;
                        writer.write(orderDataLinkedList);
                        orderDataLinkedList.clear();
                    }
                    else
                    {
                        writer.write(orderDataLinkedList);
                        orderDataLinkedList.clear();
                        System.out.println("OneBox::OK "+"选用的箱子号码:"+boxNum+" *******************OKOKOKOKOKOKOKOKOKOKOOKOKOKOKOKOKOKOKOKOKO");
                        orderSkuLinkedList.clear();
                        //包裹号码+1
                        packageNo++;
                        break;
                    }
                }
                //System.out.println("当前allOrderDataLinkedList尺寸:"+allOrderDataLinkedList.size());
            }
            //尝试装箱 2:订单商品总体积大于最大的箱子
            else
            {
                //初始化包裹号码为1
                int packageNo=1;
                LinkedList<OrderData> orderDataLinkedList = new LinkedList<>();
                //问题:这里的链表需要变化
                while(getVolumeInOrderSkuLinkedList(orderSkuLinkedList)>MAX_BOX)
                {
                    System.out.println("********************************选择箱子****************************************");
                    System.out.println("当前选择箱子编号:"+0+" , "+consumeBoxLinkedList.get(0));
                    System.out.println("************************************************************************");
                    tryAllRoom(problem,0,order_i.orderNo,packageNo,orderSkuLinkedList,orderDataLinkedList);
                    packageNo++;
                    newConsumeSet.add(new NewConsume("青柠味可乐","京东"+newConsumeNo+"箱",usedMaxLength,usedMaxWeight,usedMaxHigh));
                    newConsumeNo++;
                    writer.write(orderDataLinkedList);
                    orderDataLinkedList.clear();
                }
                if(getVolumeInOrderSkuLinkedList(orderSkuLinkedList)>0)
                {
                    //尝试用一个箱子装下
                    while(orderSkuLinkedList.size()!=0)
                    {
                        int boxNum=0;
                        boxNum=getConsumeNumInOrderSkuLinkedList(orderSkuLinkedList);
                        System.out.println("********************************选择箱子****************************************");
                        System.out.println("当前选择箱子编号:"+boxNum+" , "+consumeBoxLinkedList.get(boxNum));
                        System.out.println("************************************************************************");
                        boolean oneBoxIsOk=false;
                        orderDataLinkedList.clear();
                        while((oneBoxIsOk=tryOneBox(problem,boxNum,order_i.orderNo,packageNo,orderSkuLinkedList,orderDataLinkedList))!=true)
                        {
                            boxNum--;
                            orderDataLinkedList.clear();
                            if(boxNum<0)
                                break;
                        }
                        //一个箱子装不下则选用一个最大的箱子装再尝试用一个装,
                        if(oneBoxIsOk==false)
                        {
                            tryAllRoom(problem,0,order_i.orderNo,packageNo,orderSkuLinkedList,orderDataLinkedList);
                            newConsumeSet.add(new NewConsume("青柠味可乐","京东"+newConsumeNo+"箱",usedMaxLength,usedMaxWeight,usedMaxHigh));
                            newConsumeNo++;
                            writer.write(orderDataLinkedList);
                            orderDataLinkedList.clear();
                            packageNo++;
                        }
                        else
                        {
                            writer.write(orderDataLinkedList);
                            orderSkuLinkedList.clear();
                            orderDataLinkedList.clear();
                            packageNo++;
                            break;
                        }
                    }

                }
            }
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
        }
    }


    //获取订单商品信息:  商品-数量 对存入优先级队列
    static void getOrderIno(Order order,LinkedList<SkuSet> orderSkuLinkedList,Double orderVolume,Integer orderSkuCount)
    {
        orderSkuLinkedList.clear();
        for(Integer skuNo : order.skuNo_count.keySet())
        {
            //计算一个订单的商品数量
            int thisSkuCount=order.skuNo_count.get(skuNo);
            orderSkuCount+=thisSkuCount;
            //计算一个订单的体积
            orderVolume+=thisSkuCount*skuHashMap.get(skuNo).volume;
            //商品加入优先队列
            orderSkuLinkedList.add(new SkuSet(skuHashMap.get(skuNo),thisSkuCount));
        }
        //测试输出
        System.out.println("************************订*********单********信********息******************************************");
        System.out.println("订单号"+order.orderNo+":当前订单商品数量:"+orderSkuCount+"   "+"当前订单体积"+orderVolume);
        System.out.println("当前链表orderSkuLinkedList长度"+orderSkuLinkedList.size());
        System.out.println("************************end:订*********单********信********息******************************************");
    }

    //1:尝试一个箱子装完所有商品
    //orderSkuLinkedList体积降序
    static boolean tryOneBox(int problem,int boxNum,int orderNo,int packageNo,LinkedList<SkuSet> orderSkuLinkedList,LinkedList<OrderData> orderDataLinkedList){

        LinkedList<SkuSet> orderSku = new LinkedList<>();
        for(SkuSet ss:orderSkuLinkedList)
        {
            orderSku.add(new SkuSet(ss));
        }
        tryAllRoom(problem,boxNum,orderNo,packageNo,orderSku,orderDataLinkedList);
        if(orderSku.size()==0)
        {
            newConsumeSet.add(new NewConsume("青柠味可乐","京东"+newConsumeNo+"箱",usedMaxLength,usedMaxWeight,usedMaxHigh));
            newConsumeNo++;
            return true;
        }
        else
        {
            return false;
        }
    }


    //2:尽可能的装满一个箱子
    static void tryAllRoom(int problem,int boxNum,int orderNo,int packageNo,LinkedList<SkuSet> orderSku,LinkedList<OrderData> orderDataLinkedList)
    {
        usedMaxHigh=0;
        usedMaxWeight=0;
        usedMaxLength=0;
        String consumeName = consumeBoxLinkedList.get(boxNum).consumeName;
        //尝试用适当大小的boxroom装
        BoxRoom boxRoom = new BoxRoom(consumeBoxLinkedList.get(boxNum));


        Room room = boxRoom.roomLinkedList.get(0);
        int xBoard = room.sx;
        int yBoard = room.sy;
        int zBoard = room.sz;
        LinkedList<Room> smallRoom = new LinkedList<>();
        LinkedList<Room> currentSmallRoom = new LinkedList<>();
        int currentX=room.start.x,currentY=room.start.y,currentZ=room.start.z;
        int currentMaxX=currentX,currentMaxY=currentY,currentMaxZ=currentZ;
        while(room!=null)
        {

            if(room!=null)
            {
                //System.out.println("************************当前room空间******************************************");
                //System.out.println(room);
                //System.out.println("************************end:当前room空间******************************************");
                //当前放置商品的基准位置
                currentX=room.start.x;currentY=room.start.y;currentZ=room.start.z;
                //记录当前层最大的x,y,z
                currentMaxX=room.start.x;currentMaxY=room.start.y;currentMaxZ=room.start.z;//z 高度
            }
            //每次取最大的空间  sku体积降序
            LinkedList<Room> rightEdge = new LinkedList<>();
            if(orderSku.size()==0)
                return;
            int orderSkuNo = 0;
            Sku sku = orderSku.get(orderSkuNo).sku;
            //当前层最右侧空间
            Room r1 = new Room(new Position(currentMaxX,room.start.y,currentZ),room.start.x+room.sx-currentMaxX,room.start.y+room.sy-currentY,room.start.z+room.sz-currentZ);
            //当前游标下部分
            Room r2 = new Room(new Position(currentX,currentY,currentZ),room.start.x+room.sx-currentX,room.start.y+room.sy-currentY,room.start.z+room.sz-currentZ);
            //当前层的空间还能装下大物时循环
            while(orderSkuNo<orderSku.size())
            {
                //System.out.println("当前位置: X="+currentX+",Y="+currentY+",Z="+currentZ);
                //System.out.println("当前Max位置: X="+currentMaxX+",Y="+currentMaxY+",Z="+currentMaxZ);
                //System.out.println("当前最远位置:X="+(room.start.x+room.sx)+",Y="+(room.start.y+room.sy)+",Z="+(room.start.z+room.sz));
                //商品可放入,更新订单数据,
                if(currentX+sku.length<=room.start.x+room.sx && currentY+sku.weight<=room.start.y+room.sy && currentZ+sku.high<=room.start.z+room.sz)
                {
                    //System.out.println("一个商品加入了包裹");
                    OrderData od = new OrderData(problem,"青柠味可乐",orderNo,packageNo,consumeName,sku.skuNo,currentX,currentY,currentZ,currentX+sku.length,currentY+sku.weight,currentZ+sku.high);
                    rightEdge.add(new Room(new Position(currentX+sku.length,currentY,currentZ),currentX+sku.length,sku.weight,currentZ));
                    //System.out.println("放入了商品"+od);
                    orderDataLinkedList.add(od);
                    SkuSet temp = orderSku.get(orderSkuNo);
                    temp.count--;
                    if(temp.count==0)
                        orderSku.remove(orderSkuNo);
                    if(orderSku.size()==0)
                        return;

                    System.out.println("放入了商品前: X="+currentX+",Y="+currentY+",Z="+currentZ);
                    //上面缝隙,  最后 sz = maxZ-sz,  sz这里不更新;
                    Room addsmall = new Room(new Position(currentX,currentY,currentZ+sku.high),sku.length,sku.weight,currentZ+sku.high);
                    System.out.println("添加的本层小空间:"+addsmall.toString());
                    currentSmallRoom.add(addsmall);

                    //暂不考虑:两个商品由于长度不一致造成的空间浪费
                    if(currentX+sku.length>currentMaxX)
                    {
                        currentMaxX=currentX+sku.length;
                    }
                    if(currentY+sku.weight>currentMaxY)
                    {
                        currentMaxY=currentY+sku.weight;
                    }
                    if(currentZ+sku.high>currentMaxZ)
                    {
                        currentMaxZ=currentZ+sku.high;
                    }
                    usedMaxLength = Math.max(currentMaxX, usedMaxLength);
                    usedMaxWeight = Math.max(currentMaxY, usedMaxWeight);
                    usedMaxHigh = Math.max(currentMaxZ, usedMaxHigh);
                    //更新当前位置
                    currentY=currentY+sku.weight;
                    System.out.println("放入了商品,更新当前位置: X="+currentX+",Y="+currentY+",Z="+currentZ);
                    //System.out.println("放入了商品,更新MAX位置: X="+currentMaxX+",Y="+currentMaxY+",Z="+currentMaxZ);
                    //更新商品
                    //sku = orderSku.getFirst().sku;

                }
//                else if(problem==3 && sku.change==true && currentX+(int)Math.ceil(0.9*sku.length)<=room.start.x+room.sx && currentY+(int)Math.ceil(0.9*sku.weight)<=room.start.y+room.sy && currentZ+(int)Math.ceil(0.9*sku.high)<=room.start.z+room.sz)
//                {
//                    sku.change=false;
//                    if(currentX+sku.length>room.start.x+room.sx)
//                    {
//                        sku.length=room.start.x+room.sx-currentX;
//                    }
//                    if(currentY+sku.weight>room.start.y+room.sy)
//                    {
//                        sku.weight = room.start.y+room.sy-currentY;
//                    }
//                    if(currentZ+sku.high>room.start.z+room.sz)
//                    {
//                        sku.high =room.start.z+room.sz-currentZ;
//                    }
//                    sku.reVolume();
//                    continue;
//                }
                //X前推处理
                else
                {
                    //前推
                    if(currentX!=currentMaxX)
                    {
                        //收入空白区
                        Room blank = new Room(new Position(currentX,currentY,currentZ),currentMaxX-currentX,room.start.y+room.sy-currentY,currentZ);
                        System.out.println("添加本层空白区："+blank.toString());
                        currentSmallRoom.add(blank);
                        currentX=currentMaxX;
                        currentY=room.start.y;
                        for(Room r:rightEdge)
                        {
                            r.sx = currentMaxX-r.start.x;
                        }
                        currentSmallRoom.addAll(rightEdge);
                        rightEdge.clear();
                    }
                }
                //当前层能否存下::**此处r1与r2有重叠
                r1 = new Room(new Position(currentMaxX,room.start.y,currentZ),room.start.x+room.sx-currentMaxX,room.sy,room.start.z+room.sz-currentZ);
                r2 = new Room(new Position(currentX,currentY,currentZ),room.start.x+room.sx-currentX,room.start.y+room.sy-currentY,room.start.z+room.sz-currentZ);
                //System.out.println("r1:"+r1);
                //System.out.println("r2:"+r2);
                //System.out.println("sku:"+sku);
                orderSkuNo=0;
                while (orderSkuNo<orderSku.size())
                {
                    sku = orderSku.get(orderSkuNo).sku;
                    if(r1.ifAccommodateOnOrder(sku)==null && r2.ifAccommodateOnOrder(sku)==null)
                    {
                        orderSkuNo++;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //当前层最后的current指向剩下的一个小空间::注意去掉r1 r2重叠部分
            if(currentX==currentMaxX)
            {
                r1 = new Room(new Position(currentMaxX,room.start.y,currentZ),room.start.x+room.sx-currentMaxX,room.sy,room.start.z+room.sz-currentZ);
                currentSmallRoom.add(r1);
                //System.out.println("r3 is:"+r3);
            }
            else
            {
                if(rightEdge.size()!=0)
                {
                    for(Room r:rightEdge)
                    {
                        r.sx = currentMaxX-r.start.x;
                    }
                    currentSmallRoom.addAll(rightEdge);
                    rightEdge.clear();
                }
                if((room.start.x+room.sx-currentMaxX)*room.sy*room.start.z+room.sz-currentZ >= (room.start.x+room.sx-currentX)*(room.start.y+room.sy-currentY)*room.start.z+room.sz-currentZ)
                {
                    r1 = new Room(new Position(currentMaxX,room.start.y,currentZ),room.start.x+room.sx-currentMaxX,room.sy,room.start.z+room.sz-currentZ);
                    r2 = new Room(new Position(currentX,currentY,currentZ),room.start.x+currentMaxX-currentX,room.start.y+room.sy-currentY,room.start.z+room.sz-currentZ);
                }
                else
                {
                    r1 = new Room(new Position(currentMaxX,room.start.y,currentZ),room.start.x+room.sx-currentMaxX,currentY-room.start.y,room.start.z+room.sz-currentZ);
                    r2 = new Room(new Position(currentX,currentY,currentZ),room.start.x+room.sx-currentX,room.start.y+room.sy-currentY,room.start.z+room.sz-currentZ);
                }
                currentSmallRoom.add(r1);
                currentSmallRoom.add(r2);
                //System.out.println("r3 is:"+r3);
                //System.out.println("r4 is:"+r4);
            }

            //room重新赋值
            room = new Room(new Position(room.start.x,room.start.y,currentMaxZ),room.sx,room.sy,room.start.z+room.sz-currentMaxZ);
            if(room.ifAccommodateOnOrder(orderSku.getFirst().sku)==null)
            {
                //smallRoom.add(room);
                currentMaxZ = room.start.z+room.sz;
                room=null;
            }

            //先清空小空间,再循环
            //暂不考虑合并小空间
            for(Room r:currentSmallRoom)
            {
                r.sz = currentMaxZ-r.start.z;
                r.jisuanVolume();
            }
            smallRoom.addAll(currentSmallRoom);
            currentSmallRoom.clear();
            //融合小空间
            int count = 0;
            LinkedList<Room> toRemove = new LinkedList<>();
            while(count!=1)
            {
                if(count!=1)
                    count=1;
//                for(int i=0;i<smallRoom.size();i++)
//                {
//                    Room l = smallRoom.get(i);
//                    if(l.volume==0)
//                        toRemove.add(l);
//                    for(int j=i+1;j<smallRoom.size();j++)
//                    {
//                        Room r = smallRoom.get(j);
//                        if(!toRemove.contains(l) && !toRemove.contains(r) && l!=r && l.merge(r)==true)
//                        {
//                            System.out.println("合并后："+r.toString());
//                            count++;
//                            toRemove.add(l);
//                        }
//                    }
//
//                }
                for(Room l:smallRoom)
                {
                    if(l.volume==0)
                        toRemove.add(l);
                    for(Room r:smallRoom)
                    {
                        if(!toRemove.contains(l) && !toRemove.contains(r) && l!=r && l.merge(r)==true)
                        {
                            System.out.println("合并后："+r.toString());
                            count++;
                            toRemove.add(l);
                        }
                    }
                }
            }
            smallRoom.removeAll(toRemove);
            toRemove.clear();
            //处理小空间
            count=0;
            boolean flag = true;
            while(count!=1)
            {
                count=1;
                for(int i=0;i<smallRoom.size();i++)
                {
                    //System.out.println("*******处理小空间*******");
                    Room temp = smallRoom.get(i);
                    //System.out.println("小空间:"+temp);
                    if(!toRemove.contains(temp))
                    {
                        if(orderSku.size()==0)
                            return;
                        int osL = 0;
                        while(osL<=orderSku.size()-1)
                        {
                            Sku thisSku = orderSku.get(osL).sku;
                            Position end=null;
                            if(problem!=3 || thisSku.change==false)
                            {
                                end = temp.ifAccommodate(thisSku);
                            }
                            else
                            {
                                end = temp.ifAccommodate3(thisSku);
                            }
                            if(end!=null && end.x<=xBoard && end.y<=yBoard && end.z<=zBoard)
                            {
                                flag=true;
                                System.out.println("小空间temp中添加商品"+temp.toString()+",end:"+end.toString());
                                toRemove.add(temp);
                                usedMaxLength = Math.max(end.x, usedMaxLength);
                                usedMaxWeight = Math.max(end.y, usedMaxWeight);
                                usedMaxHigh = Math.max(end.z, usedMaxHigh);
                                orderDataLinkedList.add(new OrderData(problem,"青柠味可乐",orderNo,packageNo,consumeName,thisSku.skuNo,temp.start.x,temp.start.y,temp.start.z,end.x,end.y,end.z));
                                count++;
                                SkuSet tempsku = orderSku.get(osL);
                                tempsku.count = tempsku.count-1;
                                if(tempsku.count==0)
                                    orderSku.remove(osL);
                                if(orderSku.size()==0)
                                    return ;
                                //暂时考虑三个小空间
                                //顶部
                                smallRoom.add(new Room(new Position(temp.start.x,temp.start.y,end.z),end.x-temp.start.x,end.y-temp.start.y,temp.sz+temp.start.z-end.z));
                                //右侧
                                smallRoom.add(new Room(new Position(end.x,temp.start.y,temp.start.z),temp.sx+temp.start.x-end.x,temp.sy,temp.sz));
                                //下侧
                                smallRoom.add(new Room(new Position(temp.start.x,end.y,temp.start.z),end.x-temp.start.x,temp.sy+temp.start.y-end.y,temp.sz));
                                break;
                            }
                            osL++;
                        }



                    }
                }
                if(toRemove.size()!=0)
                    smallRoom.removeAll(toRemove);
                toRemove.clear();
                //再融合
                for(Room l:smallRoom)
                {
                    if(l.volume==0)
                        toRemove.add(l);
                    for(Room r:smallRoom)
                    {
                        if(!toRemove.contains(l) && !toRemove.contains(r) && l!=r && l.merge(r)==true)
                        {
                            System.out.println("合并后："+r.toString());
                            count++;
                            toRemove.add(l);
                        }
                    }
                }
                smallRoom.removeAll(toRemove);
                toRemove.clear();
                //最后一次融合:
                if(count==1 && flag && room==null)
                {
                    for(Room l:smallRoom)
                    {
                        for(Room r:smallRoom)
                        {
                            if(!toRemove.contains(l) && !toRemove.contains(r) && l!=r)
                            {
                                currentSmallRoom = l.mergeUD(r,currentSmallRoom);
                                System.out.println("合并后："+r.toString());
                                count++;
                                toRemove.add(l);
                            }
                        }
                    }
                    smallRoom.removeAll(toRemove);
                    smallRoom.addAll(currentSmallRoom);
                    currentSmallRoom.clear();
                    toRemove.clear();
                    flag=false;
                    count=0;
                }
            }
        }
    }

    static int getConsumeNum(Double volume)
    {
        int start = 0;
        int end = consumeBoxLinkedList.size()-1;
        while(end>start)
        {
            int mid = (start+end+1)/2;
            if(consumeBoxLinkedList.get(mid).volume>volume)
                start=mid;
            else
                end = mid-1;
        }
        //System.out.println("在consumeBoxLinkedList找到合适的箱子序号:"+start);
        return start;
    }
    static int getConsumeNumInOrderSkuLinkedList(LinkedList<SkuSet> orderSkuLinkedList)
    {
        Double volume=getVolumeInOrderSkuLinkedList(orderSkuLinkedList);
        return getConsumeNum(volume);
    }
    static Double getVolumeInOrderSkuLinkedList(LinkedList<SkuSet> orderSkuLinkedList)
    {
        Double volume=0.0;
        for(SkuSet ss:orderSkuLinkedList)
            volume+=ss.sku.volume*ss.count;
        return volume;
    }
}
